package java_thinking.unit_17._17_2_6;

import java.util.*;
import static java.util.Collections.binarySearch;

/**
 * @Desc:   使用LinkedList实现SortedSet
 *
 * true    &=    true    ==>    true
 * true    &=    false    ==>    false
 * false    &=    true    ==>    false
 * false    &=    false    ==>    false
 *
 * true    |=    true    ==>    true
 * true    |=    false    ==>    true
 * false    |=    true    ==>    true
 * false    |=    false    ==>    false
 *
 * true    ^=    true    ==>    false
 * true    ^=    false    ==>    true
 * false    ^=    true    ==>    true
 * false    ^=    false    ==>    false
 *
 * @author: cww
 * @DateTime: 2019/4/16 19:29
 */
class CustomSortedSet<T> implements SortedSet<T> {
    /**
     * final修饰的变量表示赋值之后不能再进行更改，系统赋默认值也算赋值，因此系统也不会赋默认值
     */
    private final List<T> list;

    public CustomSortedSet() {
        this.list = new LinkedList<>();
    }

    public CustomSortedSet(List<T> list) {
        this.list = list;
    }

    @Override
    public String toString() {
        return list.toString();
    }

    @Override
    public int size() {
        return list.size();
    }

    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        checkForNull(o);
        return binarySearch((List<Comparable<T>>)list, (T)o) >= 0;
    }


    @Override
    public Iterator<T> iterator() {
        return list.iterator();
    }

    @Override
    public Object[] toArray() {
        return list.toArray();
    }

    @Override
    public <T> T[] toArray(T[] a) {
        return list.toArray(a);
    }

    @Override
    public boolean add(T t) {
        checkForNull(t);
        int ip = binarySearch((List<Comparable<T>>)list,t);
        if (ip < 0) {
            ip = -(ip + 1);
            if (ip == list.size()) {
                list.add(t);
            } else {
                list.add(ip,t);
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean remove(Object o) {
        checkForNull(o);
        return list.remove(o);
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        checkForNull(c);
        return list.contains(c);
    }
    @Override
    public boolean addAll(Collection<? extends T> c) {
        checkForNull(c);
        checkForNullElements(c);
        boolean res = false;
        for (T item : c) {
            res |= add(item);
        }
        return res;
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        checkForNull(c);
        return list.removeAll(c);
    }
    @Override
    public boolean retainAll(Collection<?> c) {
        checkForNull(c);
        return list.retainAll(c);
    }

    @Override
    public void clear() {
        list.clear();
    }

    @Override
    public boolean equals(Object obj) {
        return obj instanceof CustomSortedSet && list.equals(((CustomSortedSet<?>)obj).list);
    }

    @Override
    public int hashCode() {
        return list.hashCode();
    }

    @Override
    public Comparator<? super T> comparator() {
        return null;
    }

    @Override
    public SortedSet<T> subSet(T fromElement, T toElement) {
        checkForNull(fromElement);
        checkForNull(toElement);
        int fromIndex = list.indexOf(fromElement);
        int toIndex = list.indexOf(toElement);
        checkForValidIndex(fromIndex);
        checkForValidIndex(toIndex);
        try {
            /**
             * 返回列表中指定的 fromIndex(包括)和 toIndex(不包括)之间的部分视图
             */
            return new CustomSortedSet<T>(list.subList(fromIndex,toIndex));
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    @Override
    public SortedSet<T> headSet(T toElement) {
        checkForNull(toElement);
        int toIndex = list.indexOf(toElement);
        return new CustomSortedSet<>(list.subList(0,toIndex));
    }

    @Override
    public SortedSet<T> tailSet(T fromElement) {
        checkForNull(fromElement);
        int fromIndex = list.indexOf(fromElement);
        return new CustomSortedSet<>(list.subList(fromIndex,list.size()));
    }

    @Override
    public T first() {
        return list.get(0);
    }

    @Override
    public T last() {
        return list.get(list.size() -1);
    }


    private void checkForNull(Object o) {
        if (o == null) {
            throw new NullPointerException();
        }
    }
    private void checkForNullElements(Collection<?> c) {
        for (Iterator<?> it = c.iterator(); it.hasNext();) {
            if (it.next() == null) {
                throw new NullPointerException();
            }
        }
    }
    private void checkForValidIndex(int idx) {
        if(idx == -1)
            throw new IllegalArgumentException();
    }
}
public class E10_CustomSortedSet {
    public static void main(String[] args) {
        SortedSet<String> sortedSet = new CustomSortedSet<>();
        Collections.addAll(sortedSet,"one two three four five six seven eight".split(" "));
        System.out.println(sortedSet);
        String low = sortedSet.first();
        String high = sortedSet.last();
        System.out.println("low : "+low);
        System.out.println("high : "+high);
        Iterator<String> it = sortedSet.iterator();
        for (int i =0; i<=6;i++) {
            if (i ==3) {
                low = it.next();
            } else
            if (i == 6) {
                high = it.next();
            }else {
                it.next();
            }
        }
        System.out.println("low : "+low);
        System.out.println("high : "+high);
        System.out.println(sortedSet.subSet(low,high));
        System.out.println(sortedSet.headSet(high));
        System.out.println(sortedSet.tailSet(low));
        System.out.println(sortedSet.contains("three"));
        System.out.println(sortedSet.contains("eleven"));
    }
}
